<template>
  <div class="container">
    <a-modal
      v-model:visible="visible"
      v-model:draggable="draggable"
      :title="title"
      @cancel="handleCancel"
      @before-ok="onBeforeOk"
    >

      <a-button @click="expandedAll(true)">
        <a-spin> 全部展开</a-spin>
      </a-button>
      <a-divider direction="vertical"/>
      <a-button @click="expandedAll(false)">
        <a-spin> 全部关闭</a-spin>
      </a-button>

      <a-table :columns="columns" :data="menuData" row-key="id" v-model:expandedKeys="expandedKeys"  @select="selectRow"
       @expanded-change="expand" :row-selection="rowSelection" @selectAll="selectRows"  show-empty-tree style="margin-top: 20px">
        <template #menuType="{ record }">
          <a-space>
            <a-tooltip v-if="record.menuType === 0" content="目录">
              <icon-list /> <span>[目录]</span>
            </a-tooltip>

            <a-tooltip v-if="record.menuType === 1" content="菜单">
              <icon-menu /><span>[菜单]</span>
            </a-tooltip>

            <a-tooltip v-if="record.menuType === 2" content="按钮">
              <icon-play-arrow /><span>[按钮]</span>
            </a-tooltip>

            <a-tooltip v-if="record.menuType === 3" content="接口">
              <icon-play-arrow /><span>[接口]</span>
            </a-tooltip>
          </a-space>
        </template>

        <template #hideInMenu="{ record }">
          <a-space>
            <span v-if="record.meta && record.meta.hideInMenu">是</span>
            <span v-else>否</span>
          </a-space>
        </template>

      </a-table>

    </a-modal>
  </div>
</template>

<script lang="ts">
import {defineComponent, reactive, ref} from 'vue';
import {useI18n} from 'vue-i18n';
import {menuIds,menuListTree,assignRoleMenu} from '@/api/menu';
import {Message} from "@arco-design/web-vue";
import {roleAssign} from "@/api/user";

const columns = [
  {
    title: '菜单名称',
    dataIndex: 'menuName'
  },
  {
    title: '菜单类型',
    dataIndex: 'menuType',
    slotName: 'menuType'
  },
  {
    title: '是否菜单隐藏',
    dataIndex: 'meta.hideInMenu',
    slotName: 'hideInMenu'
  }
];

export default defineComponent({
    setup(props, context) {
      const { t } = useI18n();
      const roleId = ref('')
      const menuData = ref([])
      const menuIdList = ref([])
      const expandedKeys = ref<any>([]);
      const selectedKeys= ref([]);
      const rowSelection = reactive({
        type: 'checkbox',
        showCheckedAll: true,
        checkStrictly: true,
        selectedRowKeys:selectedKeys
      });



      const loadMenuTree = async () => {
        const { data } = await menuListTree();
        menuData.value = data.menus
        menuIdList.value = data.menuIds
      };
      loadMenuTree();

      const expand = (e: any[]) => {
         expandedKeys.value = [...e];
      };
      const getAllChildIdsById = (data:[], targetId:string) => {
        const result: any[] = [];
        function collectIds(node:any) {
          result.push(node.id);
          if (node.children && node.children.length) {
            node.children.forEach(collectIds);
          }
        }
        function traverse(node:any) {
          if (node.id === targetId) {
            collectIds(node);
          } else if (node.children && node.children.length) {
            node.children.forEach(traverse);
          }
        }
        data.forEach(traverse);
        return result;
      }


      const selectRow = (rowKeys: any,rowKey:never) => {
        const include = selectedKeys.value.includes(rowKey);
        if(include){
          rowKeys =  rowKeys.filter((key: any) => key !== rowKey);
          selectedKeys.value = rowKeys
        }else{
          selectedKeys.value.push(...getAllChildIdsById(menuData.value as [],rowKey) as [])
        }
          //  selectedKeys.value.push(...getAllChildIdsById(menuData.value as [],rowKey) as [])
      };

      const selectRows = (e:any) => {
         if(e){
            selectedKeys.value = menuIdList.value
         }else{
           selectedKeys.value =[]
         }
      }

      const expandedAll = (flag:boolean) => {
        if(flag)
        expandedKeys.value = menuIdList.value;
        else
          expandedKeys.value=[]
      }




      const onBeforeOk = async (done: (arg: boolean) => void) => {
        const isOk =   selectedKeys.value.length>0;
        if (!isOk) {
          Message.error('请选择菜单');
          return false;
        }
        await assignRoleMenu({roleId:roleId.value,menuIds:selectedKeys.value});
        Message.success('操作成功!');
        return done(isOk);
      };

      return {
        t,
        columns,
        onBeforeOk,
        roleId,
        menuData,
        expandedKeys,
        selectedKeys,
        rowSelection,
        expand,
        selectRow,
        selectRows,
        menuIdList,
        expandedAll
      };
    },
    data() {
      return {
        visible: false,
        draggable: true,
        title: '',
        loading: false,
      };
    },
    methods: {
      open(id: string) {
        this.visible = true;
        this.roleId = id
        this.title = '菜单授权';
        this.queryMenuIds(id);
      },
      async queryMenuIds(id: string) {
        const { data } = await menuIds(id);
        this.selectedKeys = data
      },
      handleCancel() {
        this.visible = false;
        this.expandedKeys=[]
        this.selectedKeys =[]
      }
    },
  });
</script>

<style scoped lang="less">
  .container {
    padding: 20px;

    .keep-margin {
      margin-bottom: 20px;
    }
  }

  .form {
    width: 420px;
  }
</style>
